package com.liao.badminton.service.impl;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.liao.badminton.code.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.liao.badminton.context.BaseContextHandler;
import com.liao.badminton.redis.RedisEnum;
import com.liao.badminton.redis.RedisUtil;
import com.liao.badminton.code.util.EntityUtils;
import com.liao.badminton.code.util.CheckUtil;
import com.liao.badminton.entity.SystemLoginLog;
import com.liao.badminton.dto.SystemLoginLogDto;
import com.liao.badminton.service.SystemUsersService;
import com.liao.badminton.vo.SystemLoginLogVo;
import com.liao.badminton.mapper.SystemLoginLogMapper;
import com.liao.badminton.service.SystemLoginLogService;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

import lombok.extern.log4j.Log4j2;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import static cn.hutool.core.util.ObjectUtil.isNotEmpty;
import static com.liao.badminton.context.BaseContextHandler.getCurrentPort;

/**
 * @author liaocheng
 * @date 2024-12-23
 * description:用户登录日志
 */
@Component
@Log4j2
public class SystemLoginLogServiceImpl extends ServiceImpl<SystemLoginLogMapper, SystemLoginLog> implements SystemLoginLogService {
    @Resource
    SystemUsersService systemUsersService;

    /**
     * 新增
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, timeout = 10, rollbackFor = Exception.class)
    public Long saveSystemLoginLog(SystemLoginLogDto param) throws ProjectException {
        SystemLoginLog systemLoginLog = param.invertEntity();
        EntityUtils.setCreatAndUpdateInfo(systemLoginLog);
        this.save(systemLoginLog);
        if (ObjectUtil.isNotEmpty(systemLoginLog.getId())) {
            systemUsersService.updateLogin(systemLoginLog);
        }
        return systemLoginLog.getId();
    }
    @Override
    public void handLogin(Long userId,Integer loginType) {
        String source = BaseContextHandler.getTty();
        SystemLoginLogDto systemLoginLogDto = new SystemLoginLogDto();
        systemLoginLogDto.setUserId(userId);
        systemLoginLogDto.setLoginIp(BaseContextHandler.getCurrentIp() + ":" + getCurrentPort());
        systemLoginLogDto.setLoginSource(source);
        systemLoginLogDto.setLoginType(loginType);
        Long logId = this.saveSystemLoginLog(systemLoginLogDto);
        if (isNotEmpty(logId)) {
            //当天剩余时间
            long remainTime = DateUtil.between(DateUtil.date(), DateUtil.endOfDay(new Date()), DateUnit.SECOND);
            RedisUtil.toSaveRedis(RedisEnum.badminton_login_flag_userId, userId, logId, remainTime);
        }

    }

    /**
     * 删除
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, timeout = 10, rollbackFor = Exception.class)
    public ResponseRest deletesSystemLoginLog(SystemLoginLogDto param) throws ProjectException {
        boolean bool = this.removeByIds(param.getDelIds());
        if (bool) {
            param.getDelIds().forEach(id -> RedisUtil.toDelete(RedisEnum.CACHE_TABLE_DATA, "systemLoginLog", "id", id));
        }
        return ResponseRest.suc("deletesSystemLoginLog", true);
    }

    /**
     * 修改
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, timeout = 10, rollbackFor = Exception.class)
    public ResponseRest updateSystemLoginLog(SystemLoginLogDto param) throws ProjectException {
        SystemLoginLog systemLoginLog = param.invertEntity();
        EntityUtils.setUpdatedInfo(systemLoginLog);
        boolean bool = this.updateById(systemLoginLog);
        if (bool) {
            RedisUtil.toDelete(RedisEnum.CACHE_TABLE_DATA, "systemLoginLog", "id", param.getId());
        }
        return ResponseRest.suc("updateSystemLoginLog", true);
    }

    /**
     * 查询列表
     */
    @Override
    public ResponseRest findSystemLoginLogByPageParam(PageParam<SystemLoginLogDto> pageParam) throws ProjectException {
        CheckUtil.checkValue(pageParam, "pageParam");
        ResponseRest resp = ResponseRest.suc("findSystemLoginLogByPageParam");
        PageHelper.startPage(pageParam.getCurrent(), pageParam.getSize(), "create_time desc");
        //LambdaQueryWrapper<SystemLoginLog> query = new LambdaQueryWrapper<>();
        List<SystemLoginLog> list = baseMapper.findByPageParam(pageParam);
        List<SystemLoginLogVo> collect = list.stream().parallel().map(entity -> SystemLoginLogVo.invertToVo(entity)).collect(Collectors.toList());
        resp.setData(new PageInfo<>(collect));
        return resp;
    }

    /**
     * 查询详情
     */
    @Override
    public ResponseRest findDetail(SystemLoginLogDto param) throws ProjectException {
        Object getDate = RedisUtil.toGetDate(RedisEnum.CACHE_TABLE_DATA, "systemLoginLog", "id", param.getId());
        if (isNotEmpty(getDate)) {
            RedisUtil.toFlushExpire(RedisEnum.CACHE_TABLE_DATA, "systemLoginLog", "id", param.getId());
            return ResponseRest.suc("findDetail", (SystemLoginLogVo) getDate);
        }
        SystemLoginLogVo vo = null;
        SystemLoginLog db = this.getById(param.getId());
        if (isNotEmpty(db)) {
            vo = SystemLoginLogVo.invertToVo(db);
            RedisUtil.toSaveRedis(RedisEnum.CACHE_TABLE_DATA, "systemLoginLog", "id", param.getId(), vo, null);
        }
        return ResponseRest.suc("findDetail", vo);
    }

}
